using System;
using System.Collections.Generic;
using System.Data;
using MVP.Domain;
using MVP.ValueObject;

namespace MVP.DataAccess.Mappers
{
    public class CustomerMapper : ICustomerMapper
    {
        public const string TABLE_NAME = "Customers";
        private const string ALL_CUSTOMERS_SQL = "SELECT * FROM Customers";

        public CustomerMapper() {}

        public IList<ICustomer> GetAllCustomers()
        {
            return CreateListOfCustomersFrom(new DatabaseGateway().QueryForDataTable(ALL_CUSTOMERS_SQL));
        }

        private IList<ICustomer> CreateListOfCustomersFrom(DataTable results)
        {
            IList<ICustomer> customers = new List<ICustomer>();

            foreach (DataRow customerRow in results.Rows)
            {
                customers.Add(CreateCustomerFrom(customerRow));
            }

            return customers;
        }

        public ICustomer FindById(int customerId)
        {
            return CreateCustomerFrom(new DatabaseGateway().QueryForDataTable(Queries.FindByIDSql(customerId)).Rows[0]);
        }

        private ICustomer CreateCustomerFrom(DataRow row)
        {
            return
                new Customer(Convert.ToInt32(row[Columns.ID]), row[Columns.CUSTOMER_MNEMONIC].ToString(),
                             row[Columns.COMPANY_NAME].ToString(), row[Columns.CONTACT_NAME].ToString(),
                             row[Columns.CONTACT_TITLE].ToString(), row[Columns.ADDRESS].ToString(),
                             row[Columns.CITY].ToString(), row[Columns.REGION].ToString(),
                             row[Columns.POSTAL_CODE].ToString(), Country.FindByName(row[Columns.COUNTRY].ToString()),
                             row[Columns.PHONE].ToString(), row[Columns.FAX].ToString());
        }

        public sealed class Columns
        {
            public const string ID = "CustomerID";
            public const string CUSTOMER_MNEMONIC = "CustomerMnemonic";
            public const string COMPANY_NAME = "CompanyName";
            public const string CONTACT_NAME = "ContactName";
            public const string CONTACT_TITLE = "ContactTitle";
            public const string ADDRESS = "Address";
            public const string CITY = "City";
            public const string REGION = "Region";
            public const string POSTAL_CODE = "PostalCode";
            public const string COUNTRY = "Country";
            public const string PHONE = "Phone";
            public const string FAX = "Fax";

            private Columns() {}
        }

        private class Queries
        {
            private const string FIND_BY_ID_SQL_FORMAT = "SELECT * FROM Customers WHERE CustomerId = {0}";

            public static string FindByIDSql(int customerId)
            {
                return string.Format(FIND_BY_ID_SQL_FORMAT, customerId);
            }
        }
    }
}